<template>
  <div class="control-section component-gap">
    <h3>✈️ 轨迹规划与栅格地图（高德地图版）</h3>
    
    <!-- 高德地图显示区域 -->
    <div class="map-module">
      <h4>高德地图可视化</h4>
      <div class="map-container">
        <div id="amap-container" ref="amapContainer" class="amap-container">
          <!-- 添加加载状态 -->
          <div v-if="!map" class="map-loading">
            <div class="loading-spinner"></div>
            <p>地图加载中...</p>
            <p v-if="mapError" class="error-message">{{ mapError }}</p>
            <button @click="retryLoadMap" class="btn btn-retry">🔄 重试加载</button>
          </div>
        </div>
        
        <!-- 地图控制工具栏 -->
        <div class="map-controls">
          <button 
            @click="centerMap" 
            class="btn btn-map-control"
          >
            🎯 居中地图
          </button>
          <button 
            @click="toggleGridOverlay" 
            class="btn btn-map-control"
            :class="{ 'btn-active': showGridOverlay }"
          >
            {{ showGridOverlay ? '📏 隐藏网格' : '📏 显示网格' }}
          </button>
          <button 
            @click="clearAllWaypoints" 
            class="btn btn-map-control btn-danger"
            :disabled="localTrajectory.poses.length === 0"
          >
            🗑️ 清空路径
          </button>
          <button 
            @click="refreshMap" 
            class="btn btn-map-control"
          >
            🔄 刷新地图
          </button>
          <button 
            @click="toggleObstacleMode" 
            class="btn btn-map-control"
            :class="{ 'btn-active': obstacleMode }"
          >
            {{ obstacleMode ? '🚧 障碍物模式(开)' : '🚧 障碍物模式(关)' }}
          </button>
          <button 
            @click="clearAllObstacles" 
            class="btn btn-map-control btn-danger"
            :disabled="obstacleMarkers.length === 0"
          >
            🗑️ 清空障碍物
          </button>
        </div>
        
        <!-- 地图状态信息 -->
        <div class="map-status">
          <div class="status-item">
            <label>地图中心:</label>
            <span>({{ mapCenter.lng.toFixed(6) }}, {{ mapCenter.lat.toFixed(6) }})</span>
          </div>
          <div class="status-item">
            <label>缩放级别:</label>
            <span>{{ zoomLevel }}</span>
          </div>
          <div class="status-item">
            <label>路径点数量:</label>
            <span>{{ localTrajectory.poses.length }}</span>
          </div>
          <div class="status-item">
            <label>总轨迹长度:</label>
            <span>{{ totalDistance.toFixed(2) }} 米</span>
          </div>
          <div class="status-item">
            <label>障碍物数量:</label>
            <span>{{ obstacleMarkers.length }}</span>
          </div>
          <div class="status-item">
            <label>当前模式:</label>
            <span>{{ obstacleMode ? '障碍物添加' : '路径点添加' }}</span>
          </div>
          <!-- 新增：ROS2连接状态 -->
          <div class="status-item">
            <label>ROS2连接:</label>
            <span :class="rosConnected ? 'safe' : 'danger'">
              {{ rosConnected ? '✅ 已连接' : '❌ 未连接' }}
            </span>
          </div>
        </div>
      </div>
    </div>

    <!-- 路径点管理 -->
    <div class="waypoint-module">
      <h4>路径点设置（{{ localTrajectory.poses.length }} 个点）</h4>
      <div class="waypoint-controls">
        <!-- 添加路径点表单 -->
        <div class="add-waypoint-form">
          <div class="form-fields">
            <div class="form-field">
              <label>经度:</label>
              <input 
                type="number" 
                v-model.number="newWaypoint.lng" 
                class="waypoint-input"
                step="0.000001"
                min="-180"
                max="180"
              >
            </div>
            <div class="form-field">
              <label>纬度:</label>
              <input 
                type="number" 
                v-model.number="newWaypoint.lat" 
                class="waypoint-input"
                step="0.000001"
                min="-90"
                max="90"
              >
            </div>
            <div class="form-field">
              <label>高度 (m):</label>
              <input 
                type="number" 
                v-model.number="newWaypoint.z" 
                class="waypoint-input"
                step="0.1"
                min="0.5"
              >
            </div>
            <button 
              @click="addWaypoint" 
              class="btn btn-add"
              :disabled="!isWaypointValid()"
            >
              ➕ 添加路径点
            </button>
            <button 
              @click="addCurrentPosition" 
              class="btn btn-current"
            >
              📍 当前位置
            </button>
          </div>
        </div>
        
        <!-- 路径点列表 -->
        <div class="waypoint-list" v-if="localTrajectory.poses.length > 0">
          <div class="list-header">
            <div class="col-index">#</div>
            <div class="col-lng">经度</div>
            <div class="col-lat">纬度</div>
            <div class="col-z">高度 (m)</div>
            <div class="col-action">操作</div>
          </div>
          <div 
            v-for="(pose, index) in localTrajectory.poses" 
            :key="index" 
            class="list-row"
            :class="{ 'active': hoveredWaypoint === index }"
            @mouseenter="hoverWaypoint(index)"
            @mouseleave="hoveredWaypoint = -1"
          >
            <div class="col-index">{{ index + 1 }}</div>
            <div class="col-lng">{{ pose.pose.position.lng.toFixed(6) }}</div>
            <div class="col-lat">{{ pose.pose.position.lat.toFixed(6) }}</div>
            <div class="col-z">{{ pose.pose.position.z.toFixed(2) }}</div>
            <div class="col-action">
              <button 
                @click="removeWaypoint(index)" 
                class="btn btn-remove"
              >
                ×
              </button>
              <button 
                @click="centerOnWaypoint(index)" 
                class="btn btn-center"
              >
                🎯
              </button>
              <button 
                @click="editWaypoint(index)" 
                class="btn btn-edit"
              >
                ✏️
              </button>
            </div>
          </div>
        </div>
        <div class="empty-waypoints" v-else>
          🗺️ 暂无路径点，点击地图或使用表单添加路径点...
        </div>
        
        <!-- 路径点批量操作 -->
        <div class="waypoint-batch-actions">
          <button 
            @click="reverseWaypoints" 
            class="btn btn-reverse"
            :disabled="localTrajectory.poses.length < 2"
          >
            ↔️ 反转路径顺序
          </button>
          <button 
            @click="optimizePath" 
            class="btn btn-optimize"
            :disabled="localTrajectory.poses.length < 3"
          >
            🔄 优化路径
          </button>
          <button 
            @click="exportWaypoints" 
            class="btn btn-export"
            :disabled="localTrajectory.poses.length === 0"
          >
            📤 导出路径
          </button>
          <button 
            @click="importWaypoints" 
            class="btn btn-import"
          >
            📥 导入路径
          </button>
          <button 
            @click="generateRandomObstacles" 
            class="btn btn-obstacle"
          >
            🚧 生成障碍物
          </button>
        </div>
      </div>
    </div>

    <!-- 轨迹发送控制 -->
    <div class="trajectory-send-module">
      <div class="send-controls">
        <div class="trajectory-options">
          <label class="option-label">
            <input 
              type="checkbox" 
              v-model="trajectoryOptions.loop"
            >
            循环执行轨迹
          </label>
          <label class="option-label">
            <input 
              type="checkbox" 
              v-model="trajectoryOptions.velocity_control"
            >
            速度控制模式
          </label>
          <div class="form-field">
            <label>轨迹速度 (m/s):</label>
            <input 
              type="number" 
              v-model.number="trajectoryOptions.velocity" 
              class="waypoint-input"
              step="0.1"
              min="0.1"
              max="10"
            >
          </div>
          <div class="form-field">
            <label>安全高度 (m):</label>
            <input 
              type="number" 
              v-model.number="trajectoryOptions.safe_altitude" 
              class="waypoint-input"
              step="0.5"
              min="1.0"
              max="100"
            >
          </div>
          <!-- 新增：虚拟机IP配置 -->
          <div class="form-field">
            <label>虚拟机IP:</label>
            <input 
              type="text" 
              v-model="vmIp" 
              class="waypoint-input"
              placeholder="例如：192.168.2.175"
            >
          </div>
          <button 
            @click="connectROS" 
            class="btn btn-connect"
            :disabled="rosConnected"
          >
            🔌 连接ROS2
          </button>
          <button 
            @click="disconnectROS" 
            class="btn btn-disconnect"
            :disabled="!rosConnected"
          >
            🚫 断开ROS2
          </button>
        </div>
        
        <div class="trajectory-actions">
          <button 
            @click="publishTrajectory" 
            class="btn btn-publish"
            :disabled="localTrajectory.poses.length < 2 || !rosConnected"
          >
            📤 发布轨迹到虚拟机
          </button>
          <button 
            @click="executeTrajectory" 
            class="btn btn-execute"
            :disabled="localTrajectory.poses.length < 2 || !rosConnected || trajectoryStatus !== 'published'"
          >
            🚀 控制PX4执行轨迹
          </button>
          <button 
            @click="stopTrajectory" 
            class="btn btn-stop"
            :disabled="!rosConnected"
          >
            ⏹️ 停止PX4飞行
          </button>
          <button 
            @click="simulateUAV" 
            class="btn btn-simulate"
            :disabled="localTrajectory.poses.length < 2"
          >
            🚁 前端本地模拟飞行
          </button>
          <button 
            @click="checkCollision" 
            class="btn btn-check"
            :disabled="localTrajectory.poses.length < 2"
          >
            🛡️ 碰撞检测
          </button>
        </div>
      </div>
    </div>

    <!-- 轨迹执行状态 -->
    <div class="execution-status">
      <h4>轨迹执行状态</h4>
      <div class="status-info">
        <div class="status-item">
          <label>轨迹状态:</label>
          <span :class="getStatusClass(trajectoryStatus)">
            {{ getStatusText(trajectoryStatus) }}
          </span>
        </div>
        <div class="status-item">
          <label>已发布路径点:</label>
          <span>{{ publishedWaypoints }}</span>
        </div>
        <div class="status-item">
          <label>执行进度:</label>
          <span>{{ executionProgress }}%</span>
        </div>
        <div class="status-item">
          <label>模拟位置:</label>
          <span v-if="currentPosition">
            ({{ currentPosition.lng.toFixed(6) }}, {{ currentPosition.lat.toFixed(6) }})
          </span>
          <span v-else>未开始</span>
        </div>
        <div class="status-item">
          <label>碰撞检测:</label>
          <span :class="collisionStatus.class">{{ collisionStatus.text }}</span>
        </div>
        <div class="status-item">
          <label>ROS2响应:</label>
          <span>{{ rosResponse || '无' }}</span>
        </div>
      </div>
      
      <!-- 进度条 -->
      <div class="progress-bar" v-if="trajectoryStatus === 'executing'">
        <div 
          class="progress-fill" 
          :style="{ width: executionProgress + '%' }"
        ></div>
      </div>
    </div>

    <!-- 隐藏的文件输入框用于导入 -->
    <input 
      type="file" 
      ref="fileInput" 
      @change="handleFileImport" 
      accept=".json" 
      style="display: none"
    >

    <!-- 编辑路径点模态框 -->
    <div v-if="editingWaypoint !== null" class="modal-overlay">
      <div class="modal-content">
        <h3>编辑路径点 {{ editingWaypoint + 1 }}</h3>
        <div class="form-fields">
          <div class="form-field">
            <label>经度:</label>
            <input 
              type="number" 
              v-model.number="editWaypointData.lng" 
              class="waypoint-input"
              step="0.000001"
            >
          </div>
          <div class="form-field">
            <label>纬度:</label>
            <input 
              type="number" 
              v-model.number="editWaypointData.lat" 
              class="waypoint-input"
              step="0.000001"
            >
          </div>
          <div class="form-field">
            <label>高度 (m):</label>
            <input 
              type="number" 
              v-model.number="editWaypointData.z" 
              class="waypoint-input"
              step="0.1"
              min="0.5"
            >
          </div>
        </div>
        <div class="modal-actions">
          <button @click="saveWaypointEdit" class="btn btn-save">💾 保存</button>
          <button @click="cancelWaypointEdit" class="btn btn-cancel">❌ 取消</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
/* eslint-disable no-redeclare */
/* global AMap:readonly, ROSLIB:readonly */

export default {
  name: 'TrajectoryPlanning',
  props: {
    isConnected: {
      type: Boolean,
      required: true,
      default: false
    },
    trajectory: {
      type: Object,
      required: true,
      default: () => ({
        header: { 
          seq: 0,
          stamp: { secs: 0, nsecs: 0 },
          frame_id: 'world' 
        },
        poses: []
      })
    }
  },
  data() {
    return {
      // 高德地图实例 - 西安邮电大学长安校区
      map: null,
      mapCenter: { lng: 108.90217, lat: 34.154305 },
      zoomLevel: 16,
      showGridOverlay: true,
      obstacleMode: false,
      mapError: null,
      mapLoading: false,
      
      // 地图覆盖物
      waypointMarkers: [],
      trajectoryPolyline: null,
      uavMarker: null,
      gridLayer: null,
      obstacleMarkers: [],
      
      // 本地轨迹数据
      localTrajectory: {
        header: { 
          seq: 0,
          stamp: { secs: 0, nsecs: 0 },
          frame_id: 'world' 
        },
        poses: []
      },
      
      hoveredWaypoint: -1,
      editingWaypoint: null,
      editWaypointData: { lng: 0, lat: 0, z: 1.5 },
      
      // 新路径点数据
      newWaypoint: {
        lng: 108.90217,
        lat: 34.154305,
        z: 1.5
      },
      
      // 轨迹选项
      trajectoryOptions: {
        loop: false,
        velocity_control: false,
        velocity: 1.0,
        safe_altitude: 2.0
      },
      
      // 执行状态
      trajectoryStatus: 'idle', // idle, published, executing, completed, stopped
      publishedWaypoints: 0,
      executionProgress: 0,
      totalDistance: 0,
      collisionStatus: { class: 'safe', text: '安全' },
      
      // 模拟相关
      currentPosition: null,
      simulationInterval: null,
      currentWaypointIndex: 0,

      // ROS2 通信相关（roslib.js）
      ros: null,
      rosConnected: false,
      rosResponse: "",
      vmIp: "192.168.2.175", // 虚拟机实际IP（需替换）
      rosTopic: null,
      rosService: null,
      roslibLoaded: false
    };
  },
  watch: {
    trajectory: {
      handler(newVal) {
        this.localTrajectory = JSON.parse(JSON.stringify(newVal));
        this.updateMapDisplay();
      },
      deep: true,
      immediate: true
    },
    vmIp() {
      if (this.rosConnected) this.disconnectROS();
    }
  },
  mounted() {
    this.loadAMapScript();
    this.loadROSLibScript(); // 加载roslib.js
  },
  beforeUnmount() {
    this.destroyMap();
    this.stopSimulation();
    this.disconnectROS();
  },
  methods: {
    // 加载roslib.js（优化：确保只加载一次）
    loadROSLibScript() {
      if (this.roslibLoaded) return Promise.resolve();
      
      return new Promise((resolve, reject) => {
        if (window.ROSLIB) {
          this.roslibLoaded = true;
          resolve();
          return;
        }

        const script = document.createElement('script');
        script.src = 'https://cdn.jsdelivr.net/npm/roslib@1.3.0/build/roslib.min.js';
        script.async = true;

        script.onload = () => {
          console.log('roslib.js加载成功');
          this.roslibLoaded = true;
          this.$emit('log-message', '✅ roslib.js加载成功');
          resolve();
        };
        
        script.onerror = () => {
          console.error('roslib.js加载失败');
          this.$emit('log-message', '❌ roslib.js加载失败');
          reject(new Error('roslib.js加载失败'));
        };
        
        document.head.appendChild(script);
      });
    },

    // 连接ROS2
    async connectROS() {
      try {
        await this.loadROSLibScript(); // 确保roslib已加载
        if (!window.ROSLIB) {
          alert('roslib.js加载失败，请刷新页面重试');
          return;
        }

        // 初始化ROS连接
        this.ros = new ROSLIB.Ros({
          url: `ws://${this.vmIp}:9090` // rosbridge_websocket默认端口
        });

        // 连接成功
        this.ros.on('connection', () => {
          this.rosConnected = true;
          this.rosResponse = "已连接到ROS2节点";
          this.$emit('log-message', `✅ ROS2连接成功（${this.vmIp}:9090）`);
          
          // 订阅轨迹状态话题
          this.rosTopic = new ROSLIB.Topic({
            ros: this.ros,
            name: '/trajectory_status',
            messageType: 'std_msgs/String'
          });
          this.rosTopic.subscribe((msg) => {
            const statusData = JSON.parse(msg.data);
            this.trajectoryStatus = statusData.status;
            this.executionProgress = statusData.progress || 0;
            this.rosResponse = statusData.msg;
          });
        });

        // 连接错误
        this.ros.on('error', (error) => {
          this.rosConnected = false;
          this.rosResponse = `连接错误: ${error}`;
          this.$emit('log-message', `❌ ROS2连接错误: ${error}`);
        });

        // 连接断开
        this.ros.on('close', () => {
          this.rosConnected = false;
          this.rosResponse = "连接已断开";
          this.$emit('log-message', '🔌 ROS2连接已断开');
        });
      } catch (err) {
        alert('ROS2连接初始化失败: ' + err.message);
      }
    },

    // 断开ROS2
    disconnectROS() {
      if (this.ros) {
        if (this.rosTopic) this.rosTopic.unsubscribe();
        this.ros.close();
        this.ros = null;
        this.rosConnected = false;
        this.rosResponse = "已断开ROS2连接";
        this.$emit('log-message', '🔌 已断开ROS2连接');
      }
    },

    // 动态加载高德地图脚本
    loadAMapScript() {
      return new Promise((resolve, reject) => {
        this.mapLoading = true;
        this.mapError = null;
        
        if (typeof window.AMap !== 'undefined') {
          this.initGaodeMap().then(resolve).catch(reject);
          return;
        }

        window._AMapSecurityConfig = {
          securityJsCode: '' // 替换为你的高德地图安全密钥
        };

        const script = document.createElement('script');
        script.src = 'https://webapi.amap.com/maps?v=2.0&key=44e3439c5286e9b1ead9e9b0effb4ee2&plugin=AMap.MouseTool,AMap.PolyEditor';
        script.async = true;
        
        let loadTimeout = setTimeout(() => {
          console.error('高德地图API加载超时');
          this.mapError = '高德地图加载超时，请检查网络连接';
          this.mapLoading = false;
          this.$emit('log-message', '❌ 高德地图加载超时');
          reject(new Error('加载超时'));
        }, 10000);

        script.onload = () => {
          clearTimeout(loadTimeout);
          console.log('高德地图API加载成功');
          this.$emit('log-message', '✅ 高德地图API加载成功');
          this.initGaodeMap().then(() => {
            this.mapLoading = false;
            resolve();
          }).catch(error => {
            this.mapLoading = false;
            reject(error);
          });
        };
        
        script.onerror = () => {
          clearTimeout(loadTimeout);
          console.error('高德地图API加载失败');
          this.mapError = '高德地图API加载失败，请检查API Key和网络连接';
          this.mapLoading = false;
          this.$emit('log-message', '❌ 高德地图API加载失败');
          reject(new Error('高德地图API加载失败'));
        };
        
        document.head.appendChild(script);
      });
    },

    // 重试加载地图
    retryLoadMap() {
      this.destroyMap();
      this.loadAMapScript().catch(error => {
        console.error('重试加载地图失败:', error);
      });
    },

    // 初始化高德地图
    initGaodeMap() {
      return new Promise((resolve, reject) => {
        if (typeof window.AMap === 'undefined') {
          const error = '高德地图API未加载';
          console.error(error);
          this.mapError = error;
          this.$emit('log-message', '❌ ' + error);
          reject(new Error(error));
          return;
        }

        try {
          const container = document.getElementById('amap-container');
          if (!container) {
            const error = '地图容器未找到';
            console.error(error);
            this.mapError = error;
            this.$emit('log-message', '❌ ' + error);
            reject(new Error(error));
            return;
          }

          if (container.offsetHeight === 0) {
            console.warn('地图容器高度为0，尝试设置最小高度');
            container.style.minHeight = '500px';
          }

          this.map = new window.AMap.Map('amap-container', {
            zoom: this.zoomLevel,
            center: [this.mapCenter.lng, this.mapCenter.lat],
            viewMode: '3D',
            mapStyle: 'amap://styles/normal',
            pitch: 45,
            features: ['bg', 'road', 'building', 'point']
          });

          this.map.on('complete', () => {
            console.log('高德地图初始化完成');
            this.$emit('log-message', '🗺️ 高德地图初始化完成');
            this.setCurrentPositionToCenter();
            resolve();
          });

          this.map.on('error', (error) => {
            console.error('地图加载错误:', error);
            this.mapError = '地图加载错误: ' + error;
            this.$emit('log-message', '❌ 地图加载错误');
            reject(error);
          });

          this.addMapControls();
          this.bindMapEvents();
          this.initGridLayer();

          setTimeout(() => {
            if (this.map) {
              resolve();
            }
          }, 3000);

        } catch (error) {
          console.error('高德地图初始化失败:', error);
          this.mapError = '高德地图初始化失败: ' + error.message;
          this.$emit('log-message', '❌ 高德地图初始化失败');
          reject(error);
        }
      });
    },

    // 添加地图控件
    addMapControls() {
      if (!this.map || typeof window.AMap === 'undefined') return;
      
      try {
        this.map.addControl(new window.AMap.Scale());
        this.map.addControl(new window.AMap.ToolBar({
          position: 'LT'
        }));
        this.map.addControl(new window.AMap.HawkEye({
          position: 'RB'
        }));
        this.map.addControl(new window.AMap.MapType({
          defaultType: 0,
          position: 'RT'
        }));
      } catch (error) {
        console.warn('添加地图控件失败:', error);
      }
    },

    // 绑定地图事件
    bindMapEvents() {
      if (!this.map) return;
      
      this.map.on('click', this.handleMapClick);
      this.map.on('moveend', this.handleMapMoveEnd);
      this.map.on('zoomchange', this.handleZoomChange);
    },

    // 初始化网格图层
    initGridLayer() {
      if (!this.map || typeof window.AMap === 'undefined') return;
      
      try {
        this.gridLayer = new window.AMap.CustomLayer(null, {
          zIndex: 100,
          render: this.renderGrid.bind(this)
        });
        
        this.map.add(this.gridLayer);
        this.gridLayer.reRender();
      } catch (error) {
        console.warn('初始化网格图层失败:', error);
      }
    },

    // 渲染网格
    renderGrid() {
      if (!this.map || !this.showGridOverlay || typeof window.AMap === 'undefined') return;
      
      const container = this.map.getContainer();
      const canvas = container.querySelector('canvas');
      if (!canvas) return;
      
      const ctx = canvas.getContext('2d');
      const bounds = this.map.getBounds();
      const zoom = this.map.getZoom();
      
      const gridSize = this.calculateGridSize(zoom);
      
      ctx.strokeStyle = 'rgba(0, 100, 255, 0.4)';
      ctx.lineWidth = 1;
      ctx.setLineDash([5, 3]);
      
      const ne = bounds.getNorthEast();
      const sw = bounds.getSouthWest();
      
      for (let lng = Math.floor(sw.lng / gridSize) * gridSize; lng <= ne.lng; lng += gridSize) {
        const path = [
          new window.AMap.LngLat(lng, sw.lat),
          new window.AMap.LngLat(lng, ne.lat)
        ];
        this.drawLineOnMap(ctx, path);
      }
      
      for (let lat = Math.floor(sw.lat / gridSize) * gridSize; lat <= ne.lat; lat += gridSize) {
        const path = [
          new window.AMap.LngLat(sw.lng, lat),
          new window.AMap.LngLat(ne.lng, lat)
        ];
        this.drawLineOnMap(ctx, path);
      }
      
      ctx.setLineDash([]);
    },
    
    // 计算网格大小
    calculateGridSize(zoom) {
      if (zoom > 15) return 0.0001;    
      if (zoom > 12) return 0.0005;    
      if (zoom > 10) return 0.001;     
      if (zoom > 8) return 0.002;      
      return 0.005;                    
    },
    
    // 在地图上绘制线
    drawLineOnMap(ctx, path) {
      const pixels = path.map(coord => this.map.lngLatToContainer(coord));
      
      ctx.beginPath();
      ctx.moveTo(pixels[0].x, pixels[0].y);
      ctx.lineTo(pixels[1].x, pixels[1].y);
      ctx.stroke();
    },
    
    // 处理地图点击事件
    handleMapClick(event) {
      const lnglat = event.lnglat;
      
      if (this.obstacleMode) {
        this.addObstacle(lnglat.lng, lnglat.lat);
      } else {
        this.newWaypoint.lng = Number(lnglat.lng.toFixed(6));
        this.newWaypoint.lat = Number(lnglat.lat.toFixed(6));
        this.addWaypoint();
      }
    },
    
    // 处理地图移动结束
    handleMapMoveEnd() {
      const center = this.map.getCenter();
      this.mapCenter.lng = center.lng;
      this.mapCenter.lat = center.lat;
      this.zoomLevel = this.map.getZoom();
    },
    
    // 处理缩放变化
    handleZoomChange() {
      this.zoomLevel = this.map.getZoom();
      if (this.gridLayer) {
        this.gridLayer.reRender();
      }
    },
    
    // 添加路径点标记
    addWaypointMarker(pose, index) {
      if (!this.map || typeof window.AMap === 'undefined') {
        console.warn('地图未初始化，无法添加标记');
        return null;
      }
      
      try {
        const marker = new window.AMap.Marker({
          position: [pose.pose.position.lng, pose.pose.position.lat],
          content: this.createMarkerContent(index + 1),
          offset: new window.AMap.Pixel(-12, -12),
          title: `路径点 ${index + 1}`,
          zIndex: 100 + index
        });
        
        marker.on('click', () => {
          this.centerOnWaypoint(index);
        });
        
        marker.on('mouseover', () => {
          this.hoverWaypoint(index);
        });
        
        marker.on('mouseout', () => {
          this.hoveredWaypoint = -1;
        });
        
        this.map.add(marker);
        return marker;
      } catch (error) {
        console.error('添加路径点标记失败:', error);
        return null;
      }
    },
    
    // 创建标记点内容
    createMarkerContent(number) {
      const color = '#2ecc71';
      return `
        <div style="
          width: 24px; 
          height: 24px; 
          background: ${color}; 
          border: 2px solid white; 
          border-radius: 50%; 
          display: flex; 
          align-items: center; 
          justify-content: center; 
          color: white; 
          font-size: 12px; 
          font-weight: bold;
          box-shadow: 0 2px 4px rgba(0,0,0,0.3);
          cursor: pointer;
        ">
          ${number}
        </div>
      `;
    },
    
    // 绘制轨迹线
    updateTrajectoryLine() {
      if (this.trajectoryPolyline && this.map) {
        try {
          this.map.remove(this.trajectoryPolyline);
        } catch (error) {
          console.warn('移除轨迹线失败:', error);
        }
        this.trajectoryPolyline = null;
      }
      
      if (this.localTrajectory.poses.length < 2 || typeof window.AMap === 'undefined') return;
      
      try {
        const path = this.localTrajectory.poses.map(pose => [
          pose.pose.position.lng,
          pose.pose.position.lat
        ]);
        
        this.trajectoryPolyline = new window.AMap.Polyline({
          path: path,
          strokeColor: this.trajectoryStatus === 'executing' ? '#f39c12' : '#3498db',
          strokeWeight: 4,
          strokeOpacity: 0.8,
          strokeStyle: this.trajectoryStatus === 'executing' ? 'dashed' : 'solid',
          zIndex: 50
        });
        
        this.map.add(this.trajectoryPolyline);
        this.calculateTotalDistance();
      } catch (error) {
        console.error('更新轨迹线失败:', error);
      }
    },
    
    // 计算总距离
    calculateTotalDistance() {
      this.totalDistance = 0;
      for (let i = 1; i < this.localTrajectory.poses.length; i++) {
        const prev = this.localTrajectory.poses[i-1].pose.position;
        const curr = this.localTrajectory.poses[i].pose.position;
        this.totalDistance += this.calculateDistance(prev, curr);
      }
    },
    
    // 计算两点间距离（米）
    calculateDistance(point1, point2) {
      const R = 6371000; 
      const dLat = (point2.lat - point1.lat) * Math.PI / 180;
      const dLng = (point2.lng - point1.lng) * Math.PI / 180;
      const a = 
        Math.sin(dLat/2) * Math.sin(dLat/2) +
        Math.cos(point1.lat * Math.PI / 180) * Math.cos(point2.lat * Math.PI / 180) *
        Math.sin(dLng/2) * Math.sin(dLng/2);
      const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
      return R * c;
    },
    
    // 设置当前位置到地图中心
    setCurrentPositionToCenter() {
      if (!this.map) {
        console.warn('地图未初始化，无法设置当前位置');
        return;
      }
      
      try {
        const center = this.map.getCenter();
        if (center) {
          this.currentPosition = {
            lng: center.lng,
            lat: center.lat,
            z: 1.5
          };
          this.createUAVMarker();
        }
      } catch (error) {
        console.error('获取地图中心失败:', error);
        this.currentPosition = {
          lng: this.mapCenter.lng,
          lat: this.mapCenter.lat,
          z: 1.5
        };
        this.createUAVMarker();
      }
    },
    
    // 创建无人机标记
    createUAVMarker() {
      if (!this.map || typeof window.AMap === 'undefined' || !this.currentPosition) {
        console.warn('条件不满足，无法创建无人机标记');
        return;
      }
      
      try {
        if (this.uavMarker && this.map) {
          try {
            this.map.remove(this.uavMarker);
          } catch (error) {
            console.warn('移除旧无人机标记失败:', error);
          }
        }
        
        this.uavMarker = new window.AMap.Marker({
          position: [this.currentPosition.lng, this.currentPosition.lat],
          content: this.createUAVMarkerContent(),
          offset: new window.AMap.Pixel(-15, -15),
          zIndex: 200
        });
        
        this.map.add(this.uavMarker);
      } catch (error) {
        console.error('创建无人机标记失败:', error);
      }
    },
    
    // 创建无人机标记内容
    createUAVMarkerContent() {
      return `
        <div style="
          width: 30px; 
          height: 30px; 
          background: #9b59b6; 
          border: 2px solid white; 
          border-radius: 50%; 
          display: flex; 
          align-items: center; 
          justify-content: center; 
          color: white; 
          font-size: 16px;
          box-shadow: 0 2px 6px rgba(0,0,0,0.4);
          animation: pulse 2s infinite;
        ">
          🚁
        </div>
        <style>
          @keyframes pulse {
            0% { transform: scale(1); }
            50% { transform: scale(1.1); }
            100% { transform: scale(1); }
          }
        </style>
      `;
    },
    
    // 更新无人机位置
    updateUAVPosition(lng, lat) {
      this.currentPosition.lng = lng;
      this.currentPosition.lat = lat;
      
      if (this.uavMarker) {
        try {
          this.uavMarker.setPosition([lng, lat]);
        } catch (error) {
          console.warn('更新无人机位置失败:', error);
        }
      }
    },
    
    // 路径点悬停
    hoverWaypoint(index) {
      this.hoveredWaypoint = index;
    },
    
    // 地图控制方法
    centerMap() {
      if (this.map) {
        this.map.setZoomAndCenter(16, [108.90217, 34.154305]);
        this.$emit('log-message', '🎯 地图已居中到西安邮电大学长安校区');
      }
    },
    
    // 网格显示切换
    toggleGridOverlay() {
      this.showGridOverlay = !this.showGridOverlay;
      if (this.gridLayer) {
        this.gridLayer.reRender();
      }
      this.$emit('log-message', this.showGridOverlay ? '📏 显示网格覆盖' : '📏 隐藏网格覆盖');
    },
    
    // 障碍物模式切换
    toggleObstacleMode() {
      this.obstacleMode = !this.obstacleMode;
      if (this.map) {
        if (this.obstacleMode) {
          this.map.setDefaultCursor('crosshair');
          this.$emit('log-message', '🚧 已进入障碍物添加模式 - 点击地图添加障碍物');
        } else {
          this.map.setDefaultCursor('default');
          this.$emit('log-message', '✅ 已退出障碍物添加模式 - 点击地图添加路径点');
        }
      }
    },
    
    // 刷新地图显示
    refreshMap() {
      if (this.map) {
        this.map.setFitView();
        if (this.gridLayer) {
          this.gridLayer.reRender();
        }
        this.$emit('log-message', '🔄 刷新地图显示');
      }
    },
    
    centerOnWaypoint(index) {
      if (index >= 0 && index < this.localTrajectory.poses.length && this.map) {
        const pose = this.localTrajectory.poses[index];
        this.map.setCenter([pose.pose.position.lng, pose.pose.position.lat]);
        this.map.setZoom(17);
        this.$emit('log-message', `🎯 居中到路径点 ${index + 1}`);
      }
    },
    
    // 验证路径点
    isWaypointValid() {
      return (
        !isNaN(this.newWaypoint.lng) &&
        !isNaN(this.newWaypoint.lat) &&
        !isNaN(this.newWaypoint.z) &&
        this.newWaypoint.z >= 0.5 &&
        this.newWaypoint.lng >= -180 &&
        this.newWaypoint.lng <= 180 &&
        this.newWaypoint.lat >= -90 &&
        this.newWaypoint.lat <= 90
      );
    },
    
    // 添加路径点
    addWaypoint() {
      if (!this.isWaypointValid()) {
        alert('路径点无效！请检查坐标值（经度:-180~180, 纬度:-90~90, 高度≥0.5m）');
        return;
      }
      
      const newPose = {
        header: { frame_id: 'world' },
        pose: {
          position: {
            lng: Number(this.newWaypoint.lng.toFixed(6)),
            lat: Number(this.newWaypoint.lat.toFixed(6)),
            z: Number(this.newWaypoint.z.toFixed(2))
          },
          orientation: { x: 0, y: 0, z: 0, w: 1 }
        }
      };
      
      const updatedPoses = [...this.localTrajectory.poses, newPose];
      
      this.localTrajectory.poses = updatedPoses;
      this.updateMapDisplay();
      
      this.$emit('update:trajectory', {
        ...this.localTrajectory,
        poses: [...updatedPoses]
      });
      
      this.newWaypoint.lng += 0.0001;
      this.newWaypoint.lat += 0.0001;
      
      this.$emit('log-message', `📍 添加路径点 ${updatedPoses.length}: (${newPose.pose.position.lng.toFixed(6)}, ${newPose.pose.position.lat.toFixed(6)})`);
    },
    
    addCurrentPosition() {
      if (!this.currentPosition) {
        if (this.map) {
          try {
            const center = this.map.getCenter();
            this.currentPosition = {
              lng: center.lng,
              lat: center.lat,
              z: 1.5
            };
          } catch (error) {
            console.error('获取地图中心失败，使用默认位置:', error);
            this.currentPosition = {
              lng: this.mapCenter.lng,
              lat: this.mapCenter.lat,
              z: 1.5
            };
          }
        } else {
          this.currentPosition = {
            lng: this.mapCenter.lng,
            lat: this.mapCenter.lat,
            z: 1.5
          };
        }
      }
      
      this.newWaypoint.lng = Number(this.currentPosition.lng.toFixed(6));
      this.newWaypoint.lat = Number(this.currentPosition.lat.toFixed(6));
      this.newWaypoint.z = Number(Math.max(this.currentPosition.z, 1.5).toFixed(2));
      
      this.addWaypoint();
    },
    
    // 编辑路径点
    editWaypoint(index) {
      if (index >= 0 && index < this.localTrajectory.poses.length) {
        const pose = this.localTrajectory.poses[index].pose.position;
        this.editingWaypoint = index;
        this.editWaypointData = {
          lng: pose.lng,
          lat: pose.lat,
          z: pose.z
        };
      }
    },
    
    saveWaypointEdit() {
      if (this.editingWaypoint !== null) {
        const updatedPoses = [...this.localTrajectory.poses];
        updatedPoses[this.editingWaypoint].pose.position = { ...this.editWaypointData };
        this.updateTrajectory(updatedPoses);
        this.$emit('log-message', `✏️ 更新路径点 ${this.editingWaypoint + 1}`);
      }
      this.cancelWaypointEdit();
    },
    
    cancelWaypointEdit() {
      this.editingWaypoint = null;
      this.editWaypointData = { lng: 0, lat: 0, z: 1.5 };
    },
    
    removeWaypoint(index) {
      if (index < 0 || index >= this.waypointMarkers.length) return;
      
      const marker = this.waypointMarkers[index];
      if (marker && this.map) {
        try {
          this.map.remove(marker);
        } catch (error) {
          console.warn('移除路径点标记失败:', error);
        }
      }
      
      this.waypointMarkers.splice(index, 1);
      
      const updatedPoses = this.localTrajectory.poses.filter((_, i) => i !== index);
      this.updateTrajectory(updatedPoses);
      
      this.$emit('log-message', `🗑️ 删除路径点 ${index + 1}`);
    },
    
    // 安全清除所有路径点标记
    clearWaypointMarkers() {
      if (!this.map || !this.waypointMarkers.length) return;
      
      this.waypointMarkers = this.waypointMarkers.filter(marker => {
        if (marker && typeof marker.remove === 'function') {
          try {
            this.map.remove(marker);
            return false;
          } catch (error) {
            console.warn('移除标记失败:', error);
            return false;
          }
        }
        return false;
      });
    },
    
    clearAllWaypoints() {
      if (confirm('确定要清空所有路径点吗？')) {
        this.clearWaypointMarkers();
        
        const updatedPoses = [];
        this.localTrajectory.poses = updatedPoses;
        
        this.updateMapDisplay();
        
        this.$emit('update:trajectory', {
          ...this.localTrajectory,
          poses: [...updatedPoses]
        });
        
        this.trajectoryStatus = 'idle';
        this.publishedWaypoints = 0;
        this.executionProgress = 0;
        this.totalDistance = 0;
        
        if (this.trajectoryPolyline && this.map) {
          try {
            this.map.remove(this.trajectoryPolyline);
          } catch (error) {
            console.warn('移除轨迹线失败:', error);
          }
          this.trajectoryPolyline = null;
        }
        
        this.$emit('log-message', '🗑️ 清空所有路径点');
      }
    },
    
    // 更新轨迹数据
    updateTrajectory(poses) {
      this.localTrajectory.poses = poses;
      this.updateMapDisplay();
      this.$emit('update:trajectory', {
        ...this.localTrajectory,
        poses: [...poses]
      });
    },
    
    // 更新地图显示
    updateMapDisplay() {
      this.clearWaypointMarkers();
      
      this.localTrajectory.poses.forEach((pose, index) => {
        const marker = this.addWaypointMarker(pose, index);
        if (marker) {
          this.waypointMarkers.push(marker);
        }
      });
      
      this.updateTrajectoryLine();
    },
    
    reverseWaypoints() {
      const reversedPoses = [...this.localTrajectory.poses].reverse();
      this.updateTrajectory(reversedPoses);
      this.$emit('log-message', '↔️ 反转路径顺序');
    },
    
    optimizePath() {
      if (this.localTrajectory.poses.length < 3) return;
      
      const optimized = [...this.localTrajectory.poses].sort((a, b) => 
        a.pose.position.lng - b.pose.position.lng
      );
      this.updateTrajectory(optimized);
      
      this.$emit('log-message', '🔄 路径已优化');
    },
    
    exportWaypoints() {
      const waypoints = this.localTrajectory.poses.map(pose => ({
        lng: pose.pose.position.lng,
        lat: pose.pose.position.lat,
        z: pose.pose.position.z
      }));
      
      const dataStr = JSON.stringify(waypoints, null, 2);
      const dataBlob = new Blob([dataStr], { type: 'application/json' });
      
      const link = document.createElement('a');
      link.href = URL.createObjectURL(dataBlob);
      link.download = `trajectory_${new Date().toISOString().split('T')[0]}.json`;
      link.click();
      
      this.$emit('log-message', '📤 导出轨迹数据');
    },
    
    importWaypoints() {
      this.$refs.fileInput.click();
    },
    
    handleFileImport(event) {
      const file = event.target.files[0];
      if (!file) return;
      
      const reader = new FileReader();
      reader.onload = (e) => {
        try {
          const waypoints = JSON.parse(e.target.result);
          if (Array.isArray(waypoints)) {
            const poses = waypoints.map(wp => ({
              header: { frame_id: 'world' },
              pose: {
                position: {
                  lng: wp.lng,
                  lat: wp.lat,
                  z: wp.z || 1.5
                },
                orientation: { x: 0, y: 0, z: 0, w: 1 }
              }
            }));
            this.updateTrajectory(poses);
            this.$emit('log-message', '📥 导入轨迹数据成功');
          }
        } catch (error) {
          alert('文件格式错误！');
          console.error('导入失败:', error);
          this.$emit('log-message', '❌ 导入轨迹数据失败');
        }
      };
      reader.readAsText(file);
      
      event.target.value = '';
    },
    
    // 障碍物管理
    addObstacle(lng, lat) {
      if (!this.map || typeof window.AMap === 'undefined') return;
      
      try {
        const marker = new window.AMap.Marker({
          position: [lng, lat],
          content: this.createObstacleContent(),
          offset: new window.AMap.Pixel(-8, -8),
          zIndex: 90,
          draggable: true
        });
        
        marker.on('dragend', (event) => {
          const newPos = event.target.getPosition();
          this.$emit('log-message', `🚧 移动障碍物到: (${newPos.lng.toFixed(6)}, ${newPos.lat.toFixed(6)})`);
        });
        
        marker.on('click', () => {
          if (confirm('是否删除此障碍物？')) {
            try {
              this.map.remove(marker);
              this.obstacleMarkers = this.obstacleMarkers.filter(m => m !== marker);
              this.$emit('log-message', '🗑️ 删除障碍物');
            } catch (error) {
              console.warn('删除障碍物失败:', error);
            }
          }
        });
        
        this.map.add(marker);
        this.obstacleMarkers.push(marker);
        
        this.$emit('log-message', `🚧 添加障碍物: (${lng.toFixed(6)}, ${lat.toFixed(6)})`);
      } catch (error) {
        console.error('添加障碍物失败:', error);
      }
    },
    
    createObstacleContent() {
      return `
        <div style="
          width: 20px; 
          height: 20px; 
          background: #e74c3c; 
          border: 2px solid white; 
          border-radius: 50%; 
          box-shadow: 0 2px 6px rgba(0,0,0,0.4);
          cursor: pointer;
          display: flex;
          align-items: center;
          justify-content: center;
          color: white;
          font-size: 12px;
          font-weight: bold;
        ">🚧</div>
      `;
    },
    
    // 清除所有障碍物
    clearAllObstacles() {
      if (this.obstacleMarkers.length === 0) return;
      
      if (confirm(`确定要清除所有 ${this.obstacleMarkers.length} 个障碍物吗？`)) {
        this.obstacleMarkers.forEach(marker => {
          if (marker && this.map) {
            try {
              this.map.remove(marker);
            } catch (error) {
              console.warn('移除障碍物标记失败:', error);
            }
          }
        });
        this.obstacleMarkers = [];
        this.$emit('log-message', '🗑️ 清除所有障碍物');
      }
    },
    
    generateRandomObstacles() {
      if (!this.map) return;
      
      for (let i = 0; i < 5; i++) {
        const lng = 108.90217 + (Math.random() - 0.5) * 0.002;
        const lat = 34.154305 + (Math.random() - 0.5) * 0.002;
        this.addObstacle(lng, lat);
      }
      
      this.$emit('log-message', '🚧 在西安邮电大学长安校区周围生成5个随机障碍物');
    },
    
    // 碰撞检测
    checkCollision() {
      if (this.localTrajectory.poses.length < 2) return;
      
      let hasCollision = false;
      const safeDistance = 30;
      
      for (const pose of this.localTrajectory.poses) {
        for (const obstacle of this.obstacleMarkers) {
          if (!obstacle) continue;
          
          try {
            const obstaclePos = obstacle.getPosition();
            const distance = this.calculateDistance(
              pose.pose.position,
              { lng: obstaclePos.lng, lat: obstaclePos.lat }
            );
            
            if (distance < safeDistance) {
              hasCollision = true;
              break;
            }
          } catch (error) {
            console.warn('计算障碍物距离失败:', error);
          }
        }
        if (hasCollision) break;
      }
      
      if (hasCollision) {
        this.collisionStatus = { class: 'danger', text: '⚠️ 检测到碰撞风险' };
        this.$emit('log-message', '⚠️ 碰撞检测：发现路径与障碍物冲突');
      } else {
        this.collisionStatus = { class: 'safe', text: '✅ 路径安全' };
        this.$emit('log-message', '✅ 碰撞检测：路径安全');
      }
    },
    
    // 轨迹控制方法：发布轨迹到虚拟机
    publishTrajectory() {
      if (this.localTrajectory.poses.length < 2) {
        alert('至少需要2个路径点才能发布轨迹！');
        return;
      }
      if (!this.rosConnected) {
        alert('请先连接ROS2！');
        return;
      }
      
      // 构造ROS消息
      const trajectoryMsg = {
        type: "publish_trajectory",
        trajectory: this.localTrajectory,
        options: this.trajectoryOptions
      };

      // 发布到ROS话题
      const trajectoryTopic = new ROSLIB.Topic({
        ros: this.ros,
        name: '/frontend_trajectory',
        messageType: 'std_msgs/String'
      });
      trajectoryTopic.publish(new ROSLIB.Message({ data: JSON.stringify(trajectoryMsg) }));
      
      this.trajectoryStatus = 'published';
      this.publishedWaypoints = this.localTrajectory.poses.length;
      this.rosResponse = "正在向ROS2发布轨迹...";
      this.$emit('log-message', `📤 向ROS2发布轨迹，包含 ${this.publishedWaypoints} 个路径点`);
    },
    
    // 轨迹控制方法：控制PX4执行轨迹
    executeTrajectory() {
      if (this.localTrajectory.poses.length < 2) {
        alert('至少需要2个路径点才能执行轨迹！');
        return;
      }
      if (!this.rosConnected) {
        alert('请先连接ROS2！');
        return;
      }
      
      if (this.trajectoryStatus !== 'published') {
        this.publishTrajectory();
      }
      
      // 调用ROS服务执行轨迹
      this.rosService = new ROSLIB.Service({
        ros: this.ros,
        name: '/execute_trajectory',
        serviceType: 'std_srvs/Trigger'
      });
      
      const request = new ROSLIB.ServiceRequest({});
      this.rosService.callService(request, (result) => {
        if (result.success) {
          this.trajectoryStatus = 'executing';
          this.executionProgress = 0;
          this.rosResponse = "PX4开始执行轨迹";
          this.$emit('log-message', '🚀 开始控制PX4执行轨迹');
        } else {
          alert('执行轨迹失败: ' + result.message);
          this.rosResponse = "执行轨迹失败";
        }
      });
    },
    
    // 轨迹控制方法：停止PX4飞行
    stopTrajectory() {
      if (!this.rosConnected) {
        alert('请先连接ROS2！');
        return;
      }
      
      const stopService = new ROSLIB.Service({
        ros: this.ros,
        name: '/stop_trajectory',
        serviceType: 'std_srvs/Trigger'
      });
      
      const request = new ROSLIB.ServiceRequest({});
      stopService.callService(request, (result) => {
        if (result.success) {
          this.trajectoryStatus = 'stopped';
          this.executionProgress = 0;
          this.rosResponse = "PX4已停止飞行";
          this.$emit('log-message', '⏹️ 停止PX4飞行');
          this.stopSimulation();
        } else {
          alert('停止飞行失败: ' + result.message);
          this.rosResponse = "停止飞行失败";
        }
      });
    },
    
    // 前端本地模拟无人机飞行
    simulateUAV() {
      if (this.localTrajectory.poses.length < 2) {
        alert('至少需要2个路径点才能模拟飞行！');
        return;
      }
      
      this.stopSimulation();
      this.trajectoryStatus = 'executing';
      this.executionProgress = 0;
      this.currentWaypointIndex = 0;
      
      const startPose = this.localTrajectory.poses[0].pose.position;
      this.updateUAVPosition(startPose.lng, startPose.lat);
      
      this.animateUAVFlight();
    },
    
    // 动画无人机飞行（前端本地）
    animateUAVFlight() {
      const totalPoints = this.localTrajectory.poses.length;
      let currentSegment = 0;
      let progressInSegment = 0;
      const segmentDuration = 2000;
      
      const animate = () => {
        if (this.trajectoryStatus !== 'executing') return;
        
        progressInSegment += 16;
        
        if (progressInSegment >= segmentDuration) {
          currentSegment++;
          progressInSegment = 0;
          
          if (currentSegment >= totalPoints - 1) {
            this.trajectoryStatus = 'completed';
            this.executionProgress = 100;
            this.$emit('log-message', '✅ 前端本地模拟飞行完成');
            return;
          }
        }
        
        const startPoint = this.localTrajectory.poses[currentSegment].pose.position;
        const endPoint = this.localTrajectory.poses[currentSegment + 1].pose.position;
        
        const t = progressInSegment / segmentDuration;
        const currentLng = startPoint.lng + (endPoint.lng - startPoint.lng) * t;
        const currentLat = startPoint.lat + (endPoint.lat - startPoint.lat) * t;
        
        this.updateUAVPosition(currentLng, currentLat);
        this.executionProgress = ((currentSegment + t) / (totalPoints - 1)) * 100;
        this.currentWaypointIndex = currentSegment;
        
        if (this.trajectoryStatus === 'executing') {
          requestAnimationFrame(animate);
        }
      };
      
      animate();
    },
    
    // 停止模拟
    stopSimulation() {
      if (this.simulationInterval) {
        clearInterval(this.simulationInterval);
        this.simulationInterval = null;
      }
      this.trajectoryStatus = 'stopped';
    },
    
    // 清理资源
    destroyMap() {
      this.stopSimulation();
      
      this.clearWaypointMarkers();
      
      if (this.trajectoryPolyline && this.map) {
        try {
          this.map.remove(this.trajectoryPolyline);
        } catch (error) {
          console.warn('移除轨迹线失败:', error);
        }
        this.trajectoryPolyline = null;
      }
      
      if (this.uavMarker && this.map) {
        try {
          this.map.remove(this.uavMarker);
        } catch (error) {
          console.warn('移除无人机标记失败:', error);
        }
        this.uavMarker = null;
      }
      
      if (this.obstacleMarkers.length && this.map) {
        this.obstacleMarkers.forEach(marker => {
          if (marker) {
            try {
              this.map.remove(marker);
            } catch (error) {
              console.warn('移除障碍物标记失败:', error);
            }
          }
        });
        this.obstacleMarkers = [];
      }
      
      if (this.map) {
        try {
          this.map.destroy();
        } catch (error) {
          console.warn('销毁地图失败:', error);
        }
        this.map = null;
      }
    },
    
    getStatusClass(status) {
      const classes = {
        idle: 'status-idle',
        published: 'status-published',
        executing: 'status-executing',
        completed: 'status-completed',
        stopped: 'status-stopped'
      };
      return classes[status] || 'status-idle';
    },
    
    getStatusText(status) {
      const texts = {
        idle: '待发布',
        published: '已发布到ROS2',
        executing: 'PX4执行中',
        completed: '已完成',
        stopped: '已停止'
      };
      return texts[status] || '未知状态';
    }
  },
  emits: ['send-trajectory', 'update:trajectory', 'log-message']
};
</script>

<style scoped>
/* 整体布局样式 */
.control-section {
  margin-bottom: 25px;
  padding: 0 10px;
}

.control-section h3 {
  margin: 0 0 20px 0;
  color: #2c3e50;
  font-size: 18px;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* 地图模块样式 */
.map-module {
  margin-bottom: 20px;
  padding: 15px;
  background: #f8f9fa;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.map-module h4 {
  margin: 0 0 12px 0;
  color: #2c3e50;
  font-size: 16px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.map-container {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.amap-container {
  width: 100%;
  height: 500px;
  border: 2px solid #34495e;
  border-radius: 6px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
  position: relative;
}

/* 地图加载状态 */
.map-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  background: #f8f9fa;
  color: #666;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 10;
}

.loading-spinner {
  width: 40px;
  height: 40px;
  border: 4px solid #e0e0e0;
  border-top: 4px solid #3498db;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 10px;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.error-message {
  color: #e74c3c;
  margin-top: 10px;
  text-align: center;
}

/* 地图控制按钮 */
.btn-retry {
  background: #3498db;
  color: white;
  margin-top: 15px;
}

.map-controls {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.btn-map-control {
  background: #34495e;
  color: white;
  padding: 6px 12px;
  font-size: 12px;
}

.btn-map-control.btn-active {
  background: #3498db;
}

.btn-map-control.btn-danger {
  background: #e74c3c;
}

/* 地图状态信息 */
.map-status {
  display: flex;
  gap: 20px;
  padding: 10px;
  background: white;
  border-radius: 6px;
  border: 1px solid #e0e0e0;
  flex-wrap: wrap;
}

.status-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
}

.status-item label {
  font-weight: 600;
  color: #7f8c8d;
}

.status-item span {
  color: #2c3e50;
  font-weight: 500;
}

/* 路径点模块样式 */
.waypoint-module {
  margin-bottom: 20px;
  padding: 15px;
  background: #f8f9fa;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.waypoint-module h4 {
  margin: 0 0 12px 0;
  color: #2c3e50;
  font-size: 16px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.waypoint-controls {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.add-waypoint-form {
  padding: 10px 0;
}

.form-fields {
  display: flex;
  gap: 15px;
  align-items: flex-end;
  flex-wrap: wrap;
}

.form-field {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 120px;
}

.form-field label {
  font-weight: 600;
  color: #2c3e50;
  font-size: 14px;
}

.waypoint-input {
  padding: 8px 12px;
  border: 2px solid #e0e0e0;
  border-radius: 4px;
  font-size: 14px;
  color: #2c3e50;
  outline: none;
  transition: border-color 0.3s;
}

.waypoint-input:focus {
  border-color: #3498db;
}

/* 路径点列表 */
.waypoint-list {
  border-radius: 6px;
  overflow: hidden;
  border: 1px solid #e0e0e0;
  max-height: 300px;
  overflow-y: auto;
}

.list-header {
  display: flex;
  background: #2c3e50;
  color: white;
  font-weight: bold;
  position: sticky;
  top: 0;
}

.list-row {
  display: flex;
  background: white;
  border-bottom: 1px solid #e0e0e0;
  transition: background 0.3s;
}

.list-row:hover,
.list-row.active {
  background: #f1f2f6;
}

/* 列表列宽 */
.col-index { width: 50px; padding: 10px; text-align: center; }
.col-lng { flex: 1; padding: 10px; }
.col-lat { flex: 1; padding: 10px; }
.col-z { flex: 1; padding: 10px; }
.col-action { 
  width: 120px; 
  padding: 10px; 
  text-align: center; 
  display: flex; 
  gap: 5px; 
  justify-content: center; 
}

.empty-waypoints {
  padding: 30px;
  text-align: center;
  color: #7f8c8d;
  font-size: 14px;
  background: white;
  border-radius: 6px;
  border: 1px dashed #e0e0e0;
}

/* 路径点批量操作 */
.waypoint-batch-actions {
  display: flex;
  gap: 10px;
  padding: 5px 0;
  flex-wrap: wrap;
}

/* 轨迹发送模块 */
.trajectory-send-module {
  padding: 15px;
  background: #f8f9fa;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  margin-bottom: 20px;
}

.send-controls {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.trajectory-options {
  display: flex;
  gap: 20px;
  align-items: center;
  flex-wrap: wrap;
}

.option-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  color: #2c3e50;
  cursor: pointer;
}

.trajectory-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

/* 执行状态模块 */
.execution-status {
  padding: 15px;
  background: #f8f9fa;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.execution-status h4 {
  margin: 0 0 12px 0;
  color: #2c3e50;
  font-size: 16px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.status-info {
  display: flex;
  gap: 20px;
  flex-wrap: wrap;
  margin-bottom: 15px;
}

/* 进度条 */
.progress-bar {
  width: 100%;
  height: 8px;
  background: #e0e0e0;
  border-radius: 4px;
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  background: linear-gradient(90deg, #2ecc71, #3498db);
  transition: width 0.3s ease;
}

/* 状态文字样式 */
.status-published {
  color: #3498db;
  font-weight: bold;
}

.status-executing {
  color: #f39c12;
  font-weight: bold;
}

.status-completed {
  color: #27ae60;
  font-weight: bold;
}

.status-stopped {
  color: #e74c3c;
  font-weight: bold;
}

.status-idle {
  color: #7f8c8d;
  font-weight: bold;
}

.safe {
  color: #27ae60;
  font-weight: bold;
}

.danger {
  color: #e74c3c;
  font-weight: bold;
}

/* 模态框样式 */
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.modal-content {
  background: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  min-width: 400px;
}

.modal-content h3 {
  margin: 0 0 15px 0;
  color: #2c3e50;
}

.modal-actions {
  display: flex;
  gap: 10px;
  margin-top: 15px;
  justify-content: flex-end;
}

/* 通用按钮样式 */
.btn {
  padding: 8px 16px;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 600;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  outline: none;
}

.btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.btn:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

/* 按钮类型样式 */
.btn-add { background: #2ecc71; color: white; }
.btn-current { background: #9b59b6; color: white; }
.btn-remove { 
  background: #e74c3c; 
  color: white; 
  width: 28px; 
  height: 28px; 
  padding: 0; 
  border-radius: 50%; 
  font-size: 16px; 
  display: flex;
  align-items: center;
  justify-content: center;
}
.btn-center {
  background: #3498db;
  color: white;
  width: 28px;
  height: 28px;
  padding: 0;
  border-radius: 50%;
  font-size: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.btn-edit {
  background: #f39c12;
  color: white;
  width: 28px;
  height: 28px;
  padding: 0;
  border-radius: 50%;
  font-size: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.btn-reverse { background: #f39c12; color: white; }
.btn-optimize { background: #1abc9c; color: white; }
.btn-export { background: #34495e; color: white; }
.btn-import { background: #95a5a6; color: white; }
.btn-obstacle { background: #e67e22; color: white; }
.btn-publish { background: #3498db; color: white; }
.btn-execute { background: #2ecc71; color: white; }
.btn-stop { background: #e74c3c; color: white; }
.btn-simulate { background: #9b59b6; color: white; }
.btn-check { background: #e74c3c; color: white; }
.btn-save { background: #2ecc71; color: white; }
.btn-cancel { background: #95a5a6; color: white; }
.btn-connect { background: #3498db; color: white; }
.btn-disconnect { background: #e74c3c; color: white; }

/* 响应式样式 */
@media (max-width: 768px) {
  .amap-container {
    height: 400px;
  }
  
  .form-fields {
    flex-direction: column;
    align-items: stretch;
  }
  
  .list-header, .list-row {
    flex-direction: column;
  }
  
  .col-index, .col-lng, .col-lat, .col-z, .col-action {
    width: auto;
    padding: 8px;
    border-bottom: 1px solid #e0e0e0;
    text-align: left;
  }
  
  .col-action {
    justify-content: flex-start;
  }
  
  .waypoint-batch-actions,
  .trajectory-actions {
    flex-direction: column;
  }
  
  .send-controls {
    flex-direction: column;
  }
  
  .trajectory-options {
    justify-content: center;
  }
  
  .status-info {
    flex-direction: column;
    gap: 10px;
  }
  
  .map-status {
    flex-direction: column;
    gap: 10px;
  }
  
  .map-controls {
    flex-direction: column;
  }
  
  .modal-content {
    min-width: 90%;
    margin: 20px;
  }
}
</style>